<?php
  class Application_Model_Menu extends Zend_Db_Table_Abstract{
  	const IND_ATIVO = 1;
    const IND_INATIVO = 0;
    
    /* Seta a tabela a ser usada*/
    protected function _setup(){
      $this->_name = 'menu';
      
      parent::_setup();
    }
    
    /**
     * Retorna a string SELECT como todos os campos solicitados por parametro.
     * @param array Array com as opções de colunas e clausulá WHERE.
     *              Ex: Colunas:
     *                  $arrOptions['fields_menu'] = array('campo1', 'campo2', 'campoN')
     *                  $arrOptions['fields_menu_perfil'] = array('campo1', 'campo2', 'campoN')
     *                  $arrOptions['fields_perfil'] = array('campo1', 'campo2', 'campoN').
     *                  
     *                  WHERE
     *                    $arrOptions['where_clause'] = array('ds_menu' => 'Cadastro')
     * @param string  Comparação.Ex: =, LIKE NOT LIKE, etc  
     *                    
     * @return string                   
     */
    public function _getMenu($arrOptions = array(), $strComparison = '='){
    	$arrAliasMenu       = array('m' => $this->_name);  
      $arrAliasPerfil     = array('p' => 'perfil');
      $arrAliasMenuPerfil = array('mp' => 'menu_perfil');
      
      if(isset($arrOptions['fields_menu']))
        $arrColsMenu = $arrOptions['fields_menu'];
      else
        $arrColsMenu = array('m.*');

      if(isset($arrOptions['fields_menu_perfil']))
        $arrColsMenuPerfil = $arrOptions['fields_menu_perfil'];
      else
        $arrColsMenuPerfil = array('mp.*');
        
      if(isset($arrOptions['fields_perfil']))
        $arrColsPerfil = $arrOptions['fields_perfil'];
      else
        $arrColsPerfil = array('p.*');
          
    	$strSql = $this->getAdapter()
    	->select()
    	->from($arrAliasMenu, $arrColsMenu)
    	->join($arrAliasMenuPerfil, 'mp.idMenu = m.idMenu', $arrColsMenuPerfil)
    	->join($arrAliasPerfil, 'p.idPerfil = mp.idPerfil', $arrColsPerfil);
    	
    	if(isset($arrOptions['where_clause']))
        foreach($arrOptions['where_clause'] as $strkey => $strValue)
    	     $strSql->where($strkey . $strComparison . ' ?', $strValue);
    	     
    	return $strSql;
    }
    
    /**
     * Retorna o menu de acordo com perfil
     * 
     * @param integer Id do perfil
     * @return databasen result
     */
    public function getMenu($intIdPerfil = null){
    	if($intIdPerfil == null)
        return false;

      $arrOptions['fields_menu'] = array(
        'm.idMenu',
        'm.ds_menu',
        'm.ds_controller',
        'm.ds_action',
        'm.ds_situacao',
        'm.idParent',  
      );
      
      $arrOptions['fields_menu_perfil'] = array();
      
      $arrOptions['fields_perfil'] = array(
        'p.idPerfil'      
      );
      
      $arrOptions['where_clause'] = array(
        'm.ds_situacao' =>  self::IND_ATIVO,
        'p.idPerfil'    => $intIdPerfil,
        'm.idParent'    => '0'        
      );
      
      $strSql = $this->_getMenu($arrOptions);  
        
      $objResult = $this->getAdapter()->fetchAll($strSql);
        
      return Core_Commons::onLoad($objResult);
    }
    
    /**
     * Retorna os submenus de acordo com o perfil e menu parent
     * 
     * @param integer Id do perfil
     * @param integer Id do menu parent
     * @return database result
     */
    public function getParentMenu($intIdPerfil = null, $intIdMenu){
      if($intIdPerfil == null)
        return false;

      $arrOptions['fields_menu'] = array(
        'm.idMenu',
        'm.ds_menu',
        'm.ds_controller',
        'm.ds_action',
        'm.ds_situacao',
        'm.idParent',  
      );
      
      $arrOptions['fields_menu_perfil'] = array();
      
      $arrOptions['fields_perfil'] = array(
        'p.idPerfil'      
      );
      
      $arrOptions['where_clause'] = array(
        'm.ds_situacao' =>  self::IND_ATIVO,
        'p.idPerfil'  => $intIdPerfil,
        'm.idParent'  => $intIdMenu         
      );
      
      $strSql = $this->_getMenu($arrOptions)
      ->order('m.ds_menu');
                     
      $objResult = $this->getAdapter()->fetchAll($strSql);
        
      return Core_Commons::onLoad($objResult);
    }
    
    /**
     * Retorna as colunas da tabela corrente
     * 
     * @return database result
     */
    public function getColunas(){
      $arrResult = array();
      $arrCols = $this->fetchAll()->getTable()->_metadata;
      $arrResult[strtoupper($this->_name)] = $arrCols;
      return Core_Commons::onLoad($arrResult);
    }
    
    /**
     * Retorna todos os registros inativos.
     * 
     * @return database result
     */
    public function getInativos(){
      $strSql = $this->select()->where($this->_name . '.ds_situacao = ?', self::IND_INATIVO);
      
      $objResult = $this->fetchAll($strSql);
            
      return Core_Commons::onLoad($objResult);
    }
    
    /**
     * Retorna todos s registro de acordo co mo id
     */
    public function getById($intId){
    	$arrAliasMenuParent = array('mpa' => 'menu');
    	$arrColsMenuParent = array(
        'idParent'  => 'm.idMenu', 
        'm.ds_menu'
    	);
    	
    	$arrOptions['fields_menu'] = array(
        'mpa.idMenu',
        'ds_father' => 'mpa.ds_menu',
        'mpa.ds_controller',
        'mpa.ds_action',
        'mpa.ds_situacao',  
      );
      
      $arrOptions['fields_menu_perfil'] = array();
      
      $arrOptions['fields_perfil'] = array(
        'p.idPerfil',
        'p.ds_perfil'     
      );
      
      $arrOptions['where_clause'] = array(
        'mpa.idMenu' => $intId 
      );
      
      $strSql = $this->_getMenu($arrOptions)
      ->join($arrAliasMenuParent, 'mpa.idParent = m.idMenu', $arrColsMenuParent)
      ;  
    	
      $objResult = $this->getAdapter()->fetchRow($strSql);
                      
      return Core_Commons::onLoad($objResult);
    }
    
    /**
     * Retorna o resultado de acordo com o nome. 
     * 
     * @param string  Nome do menu
     * @param string  Nome da controller
     * 
     * @return database_result
     */
    public function getByMenuEController($strDsMenu, $strDsController){
    	$arrOptions['fields_menu'] = array(
    	  'idMenu', 
        'ds_menu',
    	  'ds_controller',
        'ds_action',
        'ds_situacao'    
    	);
    	
    	$arrOptions['fields_menu_perfil'] = array();
    	
    	$arrOptions['fields_perfil'] = array(
        'ds_perfil'    	 
    	);
    	
    	$arrOptions['where_clause'] = array(
        'p.idPerfil'  => '1',
    	  'm.idParent'  => '0'       	 
    	);
    	
      if($strDsMenu && $strDsController){ 
        $arrOptions['where_clause'] = array(
          'm.ds_menu'       => '%' . $strDsMenu . '%',
          'm.ds_controller' => '%' . $strDsController . '%'         
        );   

        $strComparison = ' LIKE ';
      }  
      elseif($strDsMenu && !$strDsController){
      	$arrOptions['where_clause'] = array(
          'm.ds_menu'       => '%' . $strDsMenu . '%',     
        );   
        
        $strComparison = ' LIKE ';
      }
      elseif(!$strDsMenu && $strDsController){
      	$arrOptions['where_clause'] = array(
          'm.ds_controller' => '%' . $strDsController . '%'         
        );   

        $strComparison = ' LIKE ';
      }
      else{
      	$arrOptions['where_clause'] = array(
          '1' => '1'         
        );   

        $strComparison = ' = ';
      }
      
      $strSql = $this->_getMenu($arrOptions, $strComparison);
      $objResult = $this->getAdapter()->fetchAll($strSql);            
      return Core_Commons::onLoad($objResult);
    }
    
    /**
     * Realiza a validação dos dados vindo do formulário
     * 
     * @return void.
     */
    public function validaForm(){
      $objValida = new Core_ValidaFormulario();
      $arrFilters = array('*' =>  'StringTrim');
      $arrOptions = array('allowEmpty' =>  true);
      
      $arrValidators = array(
        'Menu'        =>  array('allowEmpty'  => false, 'fields' => 'ds_father'),
        'Controller'  =>  array('allowEmpty'  => false, 'fields' => 'ds_controller'),
        'Action'      =>  array('allowEmpty'  => false, 'fields' => 'ds_action'),
        'Perfil'      =>  array('allowEmpty'  => false, 'fields' => 'idPerfil'),
        'Parent'      =>  array('allowEmpty'  => false, 'fields' => 'idParent'),
        'Situação'    =>  array('allowEmpty'  => false, 'fields' => 'ds_situacao'),
        'Inserção'    =>  array('allowEmpty'  => false, 'fields' => 'dt_insercao'),
      );
      
      return $objValida->validaFormulario($arrFilters, $arrValidators, $arrOptions);;
    }
    
    /**
     * Salva um registro. Funcionalidade para inserção e atualização
     * @param integer Id do registro. Se for diferente de null, então será atualizado o regsitro
     * a partir do id, senão será inserido um novo registro.
     * 
     * @return boolean.
     */
    public function salvar($intIdMenu = null, $intIdPerfil = null){
      $objValida = new Core_ValidaFormulario();
      $objDadosInput = $this->validaForm();
                              
      $arrDadosM['ds_menu']        = ucfirst($objDadosInput->ds_father);
      $arrDadosM['ds_controller']  = strtolower($objDadosInput->ds_controller);
      $arrDadosM['ds_action']      = strtolower($objDadosInput->ds_action);
      $arrDadosM['idParent']       = $objDadosInput->idParent;
      $arrDadosM['ds_situacao']    = $objDadosInput->ds_situacao;

      $arrDadosP['idPerfil']       = $objDadosInput->idPerfil;
      
      if($intIdMenu == null && $intIdPerfil == null){
        $arrDadosM['dt_insercao']    = date('Y-m-d H:i:s');
        $arrDadosM['dt_atualizacao'] = 'NULL';
            
        $strSql = $this->select()
        ->where("ds_menu = ?", $arrDadosM['ds_menu'])
        ->where("ds_controller = ?", $arrDadosM['ds_controller'])
        ->where("ds_action = ?", $arrDadosM['ds_action'])
        ;
        
        if($this->fetchAll($strSql)->current())
          throw new Exception('Menu já cadastrado com o nome "' . $arrDados['ds_menu'] . '", controller "' . $arrDados['ds_controller'] . '" e action "' . $arrDados['ds_action'] . '"!', '3');
        else{
        	if($this->insert($arrDadosM)){
        		$arrDadosP['idMenu'] = $this->getAdapter()->lastInsertId($this->_name, 'idMenu');
            
            return $this->getAdapter()->insert('menu_perfil', $arrDadosP);
        	}
        	else
        	 throw new Exception('Não foi possível inserir o menu', '4');
        }  
      }
      else{ 
        $arrDadosM['dt_atualizacao'] = date('Y-m-d H:i:s');
                
        //if(
        $this->update($arrDadosM, 'idMenu = ' . $intIdMenu);//){
          $strWhere =  'idMenu = ' . $intIdMenu . ' AND idPerfil = ' . $intIdPerfil;       	
          
          $this->getAdapter()->update('menu_perfil', $arrDadosP, $strWhere);
          
          return true;
        //}  
        //else
          //throw new Exception('Não foi possível atualizar o menu', '4');
      }
    }
    
    /**
     * Exclui um registro  a partir do banco de dados.
     * Um registro nunca será ecluido do banco de dados.
     * Considera-se excluído um registro com status igual a "0".
     * 
     * @param integer  id para a clausula where.
     * @return boolean.
     */
    public function excluir($intId){
      $boolReturn = false;
      $objDadosInput = $this->validaForm();
      
      $strWhere = "idMenu = '" . $intId . "'";
      $arrDados['ds_situacao'] = self::IND_INATIVO; 
      $arrDados['dt_atualizacao'] = date('Y-m-d H:i:s');
            
      if($this->update($arrDados, $strWhere))  
        $boolReturn = true;
      
      return $boolReturn; 
      
    }
  }  